import numpy as np
from cv2 import cv2
# 这个成功的扣下了ppt白板
#srcPic = cv2.imread(r'image-XS\juxing.jpg')
def judge_pos(center, length, depth, result, st) :
    center[0] = (st[0][0] + st[1][0] + st[2][0] + st[3][0]) / 4
    center[1] = (st[0][1] + st[1][1] + st[2][1] + st[3][1]) / 4
    #print(center)
    result = result.append(center)
    range_len=[1,2]
    range_dep=[1,2]
    range_len[0] = length * 0.45
    range_len[1] = length * 0.55
    range_dep[0] = depth * 0.45
    range_dep[1] = depth *0.55 
    if center[0] > range_len[0] and center[0] < range_len[1] and center[1] > range_dep[0] and center[1] < range_dep[1]:
        return True
    else:
        return False


def judge_para(st, length, depth):
    shu = abs(st[0][0] - st[1][0])
    heng = abs(st[1][1] - st[2][1])
    if shu < depth * 0.05 and heng < length * 0.05:
        return True
    else:
        return False


#cap = cv2.VideoCapture(0    , cv2.CAP_DSHOW)
#result = []
#while(cap.isOpened()):
#    ret,srcPic = cap.read()
#    if ret == True:
#        length=srcPic.shape[0]
#        depth=srcPic.shape[1]
#        polyPic = srcPic
#        shrinkedPic = srcPic
#        greyPic = cv2.cvtColor(shrinkedPic, cv2.COLOR_BGR2GRAY)              #将图片转换为灰度图
#        ret, binPic = cv2.threshold(greyPic, 130, 255, cv2.THRESH_BINARY)    #图像二值化
#        #print(binPic.shape)                                                  #输出图像大小，格式为元组
#        median = cv2.medianBlur(binPic, 5)                                   #中值滤波函数，计算量较大，不存在细节模糊等问题
#        cannyPic = cv2.Canny(median, 10, 200)                                #Canny边缘检测，被认为边缘检测最优算法
#
#        #cv2.namedWindow("binary", 0)                                         #输出边缘检测后的图片
#        #cv2.namedWindow("binary2", 0)
#        #cv2.imshow("binary", cannyPic)
#        # 找出轮廓
#        contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
#        #cv2.imwrite('binary2.png', cannyPic)
#        #cv2.imshow("binary2", cannyPic)
#        i = 0
#        maxArea = 0
#        # 挨个检查看那个轮廓面积最大
#        for i in range(len(contours)):
#            if cv2.contourArea(contours[i]) > cv2.contourArea(contours[maxArea]):   
#                maxArea = i
#        #检查轮廓得到分布在四个角上的点
#        #print(len(contours))
#        if len(contours) != 0:
#            hull = cv2.convexHull(contours[maxArea])    #凸包
#            s = [[1,2]]
#            z = [[2,3]]
#            for i in hull:
#                s.append([i[0][0],i[0][1]])
#                z.append([i[0][0],i[0][1]])
#            del s[0]
#            del z[0]
#
#            #现在的目标是从一堆点中挑出分布在四个角落的点，决定把图片分为四等份，每个区域的角度来划分点，
#            #默认四个角分别分布在图像的四等分的区间上，也就是矩形在图像中央
#            # 我们把所有点的坐标，都减去图片中央的那个点（当成原点），然后按照x y坐标值的正负 判断属于哪一个区间
#
#            center=[length/2,depth/2]
#
#            # 可以得到小数
#            for i in range(len(s)):
#                s[i][0] = s[i][0] - center[0]
#                s[i][1] = s[i][1] - center[1]
#            one = []
#            two = []
#            three = []
#            four = []
#            # 判断是那个区间的
#            for i in range(len(z)):
#                if s[i][0] <= 0 and s[i][1] <0 :
#                    one.append(i)
#                elif s[i][0] > 0 and s[i][1] <0 :
#                    two.append(i)
#                elif s[i][0] >= 0 and s[i][1] > 0:
#                    four.append(i)
#                else:three.append(i)
#
#            p=[]
#            distance=0
#            temp = 0
#            # 下面开始判断每个区间的极值,要选择距离中心点最远的点，就是角点
#            for i in one :
#                x=z[i][0]-center[0]
#                y=z[i][1]-center[1]
#                d=x*x+y*y
#                if d > distance :
#                    temp = i
#                    distance = d
#            p.append([z[temp][0],z[temp][1]])
#            distance=0
#            temp=0
#            for i in two :
#                x=z[i][0]-center[0]
#                y=z[i][1]-center[1]
#                d=x*x+y*y
#                if d > distance :
#                    temp = i
#                    distance = d
#            p.append([z[temp][0],z[temp][1]])
#            distance=0
#            temp=0
#            for i in three :
#                x=z[i][0]-center[0]
#                y=z[i][1]-center[1]
#                d=x*x+y*y
#                if d > distance :
#                    temp = i
#                    distance = d
#            p.append([z[temp][0],z[temp][1]])
#            distance=0
#            temp=0
#            for i in four :
#                x=z[i][0]-center[0]
#                y=z[i][1]-center[1]
#                d=x*x+y*y
#                if d > distance :
#                    temp = i
#                    distance = d
#            p.append([z[temp][0],z[temp][1]])
#
#
#            for i in p:
#                cv2.circle(polyPic, (i[0],i[1]),2,(0,255,0),2)
#            # 给四个点排一下顺序
#            a=[]
#            b=[]
#            st=[]
#            center=[1,2]
#            for i in p:
#                a.append(i[0])
#                b.append(i[1])
#            index=np.lexsort((b, a))
#            for i in index:
#                st.append(p[i])
#            p = st
#            print(p)
#            pts1 = np.float32([[p[0][0],p[0][1]],[p[1][0],p[1][1]],[p[2][0],p[2][1]],[p[3][0],p[3][1]]])
#            ## dst=np.float32([[0,0],[0,srcPic.shape[1]],[srcPic.shape[0],0],[srcPic.shape[0],srcPic.shape[1]]])
#            dst=np.float32([[0,0],[0,600],[400,0],[400,600]])
#            #
#            ## 投影变换
#            M = cv2.getPerspectiveTransform(pts1,dst)
#            #cv2.namedWindow("srcPic2", 0)
#            #cv2.imshow("srcPic2", srcPic)
#            #dstImage = cv2.warpPerspective(srcPic,M,(srcPic.shape[0],srcPic.shape[1]))
#            dstImage = cv2.warpPerspective(srcPic,M,(400,600))
#            #
#            #
#            ## 在原图上画出红色的检测痕迹，先生成一个黑色图
#            #black = np.zeros((shrinkedPic.shape[0], shrinkedPic.shape[1]), dtype=np.uint8)
#            ## 二值图转为三通道图
#            #black3 = cv2.merge([black, black, black])
#            ## black=black2
#            #cv2.drawContours(black, contours, maxArea, 255, 11)
#            #cv2.drawContours(black3, contours, maxArea, (255, 0, 0), 11)
#            ##cv2.imwrite('cv.png', black)
#            #
#            #cv2.namedWindow("cannyPic", 0)
#            #cv2.imshow("cannyPic", black)
#            #cv2.namedWindow("shrinkedPic", 0)
#            #cv2.imshow("shrinkedPic", polyPic)
#            cv2.namedWindow("dstImage", 0)
#            cv2.imshow("dstImage", dstImage)
#            # 等待一个按下键盘事件
#            #cv2.waitKey(0)
#            ## 销毁所有创建出的窗口
#            #cv2.destroyAllWindows()
#            cv2.imshow('srcPic',srcPic)
#            if judge_pos(center, length, depth, result) & judge_para(st, length, depth):          #判断矩形中心是否在视频中心
#                break
#        if cv2.waitKey(1) & 0xFF == ord('q'):
#            break 
#    else:
#        break
##print(result)
#cap.release
#cv2.destroyAllWindows()



def detect(srcPic):
    length=srcPic.shape[0]
    depth=srcPic.shape[1]
    polyPic = srcPic
    shrinkedPic = srcPic
    greyPic = cv2.cvtColor(shrinkedPic, cv2.COLOR_BGR2GRAY)              #将图片转换为灰度图
    ret, binPic = cv2.threshold(greyPic, 130, 255, cv2.THRESH_BINARY)    #图像二值化
    #print(binPic.shape)                                                  #输出图像大小，格式为元组
    median = cv2.medianBlur(binPic, 5)                                   #中值滤波函数，计算量较大，不存在细节模糊等问题
    cannyPic = cv2.Canny(median, 10, 200)                                #Canny边缘检测，被认为边缘检测最优算法
    #cv2.namedWindow("binary", 0)                                         #输出边缘检测后的图片
    #cv2.namedWindow("binary2", 0)
    #cv2.imshow("binary", cannyPic)
    # 找出轮廓
    contours, hierarchy = cv2.findContours(cannyPic, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
    #cv2.imwrite('binary2.png', cannyPic)
    #cv2.imshow("binary2", cannyPic)
    i = 0
    maxArea = 0
    # 挨个检查看那个轮廓面积最大
    for i in range(len(contours)):
        if cv2.contourArea(contours[i]) > cv2.contourArea(contours[maxArea]):   
            maxArea = i
    #检查轮廓得到分布在四个角上的点
    #print(len(contours))
    if len(contours) != 0:
        hull = cv2.convexHull(contours[maxArea])    #凸包
        s = [[1,2]]
        z = [[2,3]]
        for i in hull:
            s.append([i[0][0],i[0][1]])
            z.append([i[0][0],i[0][1]])
        del s[0]
        del z[0]
        #现在的目标是从一堆点中挑出分布在四个角落的点，决定把图片分为四等份，每个区域的角度来划分点，
        #默认四个角分别分布在图像的四等分的区间上，也就是矩形在图像中央
        # 我们把所有点的坐标，都减去图片中央的那个点（当成原点），然后按照x y坐标值的正负 判断属于哪一个区间
        center=[length/2,depth/2]
        # 可以得到小数
        for i in range(len(s)):
            s[i][0] = s[i][0] - center[0]
            s[i][1] = s[i][1] - center[1]
        one = []
        two = []
        three = []
        four = []
        # 判断是那个区间的
        for i in range(len(z)):
            if s[i][0] <= 0 and s[i][1] <0 :
                one.append(i)
            elif s[i][0] > 0 and s[i][1] <0 :
                two.append(i)
            elif s[i][0] >= 0 and s[i][1] > 0:
                four.append(i)
            else:three.append(i)
        p=[]
        distance=0
        temp = 0
        # 下面开始判断每个区间的极值,要选择距离中心点最远的点，就是角点
        for i in one :
            x=z[i][0]-center[0]
            y=z[i][1]-center[1]
            d=x*x+y*y
            if d > distance :
                temp = i
                distance = d
        p.append([z[temp][0],z[temp][1]])
        distance=0
        temp=0
        for i in two :
            x=z[i][0]-center[0]
            y=z[i][1]-center[1]
            d=x*x+y*y
            if d > distance :
                temp = i
                distance = d
        p.append([z[temp][0],z[temp][1]])
        distance=0
        temp=0
        for i in three :
            x=z[i][0]-center[0]
            y=z[i][1]-center[1]
            d=x*x+y*y
            if d > distance :
                temp = i
                distance = d
        p.append([z[temp][0],z[temp][1]])
        distance=0
        temp=0
        for i in four :
            x=z[i][0]-center[0]
            y=z[i][1]-center[1]
            d=x*x+y*y
            if d > distance :
                temp = i
                distance = d
        p.append([z[temp][0],z[temp][1]])
        for i in p:
            cv2.circle(polyPic, (i[0],i[1]),2,(0,255,0),2)
        # 给四个点排一下顺序
        a=[]
        b=[]
        st=[]
        center=[1,2]
        for i in p:
            a.append(i[0])
            b.append(i[1])
        index=np.lexsort((b, a))
        for i in index:
            st.append(p[i])
        p = st
        #print(p)
        #pts1 = np.float32([[p[0][0],p[0][1]],[p[1][0],p[1][1]],[p[2][0],p[2][1]],[p[3][0],p[3][1]]])
        ## dst=np.float32([[0,0],[0,srcPic.shape[1]],[srcPic.shape[0],0],[srcPic.shape[0],srcPic.shape[1]]])
        #dst=np.float32([[0,0],[0,600],[400,0],[400,600]])
        #
        ## 投影变换
        #M = cv2.getPerspectiveTransform(pts1,dst)
        cv2.namedWindow("srcPic", 0)
        cv2.imshow("srcPic", srcPic)
        #dstImage = cv2.warpPerspective(srcPic,M,(srcPic.shape[0],srcPic.shape[1]))
        #dstImage = cv2.warpPerspective(srcPic,M,(400,600))
        if judge_pos(center, length, depth, result, st) & judge_para(st, length, depth):
            return True

cap = cv2.VideoCapture(0)
result = []
while(cap.isOpened()):
    ret,srcPic = cap.read()
    if ret == True:
        if detect(srcPic) == True:
            break
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break 
    else:
        break
cap.release()
cv2.destroyAllWindows()